package com.tjf.lib_core;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;

import com.gyf.immersionbar.BarHide;
import com.gyf.immersionbar.ImmersionBar;
import com.tjf.lib_core.action.ActivityAction;
import com.tjf.lib_core.action.BundleAction;
import com.tjf.lib_core.action.ClickAction;
import com.tjf.lib_core.action.HandlerAction;
import com.tjf.lib_core.action.KeyboardAction;
import com.tjf.lib_network.HttpHelper;
import com.tjf.lib_network.okhttp.TokenCallBack;
import com.tjf.lib_utils.EasyWindowUtils;
import com.tjf.lib_utils.EventBusUtils;
import com.tjf.lib_utils.LogsUtils;
import com.tjf.lib_utils.ShareUtils;
import com.tjf.lib_utils.bean.BusEvent;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;
import java.util.Random;

import butterknife.ButterKnife;


/**
 * Activity 技术基类
 */
public abstract class BaseActivity extends AppCompatActivity
        implements ActivityAction, ClickAction,
        HandlerAction, BundleAction, KeyboardAction, TokenCallBack {

    /**
     * 错误结果码
     */
    public static final int RESULT_ERROR = -2;

    /**
     * Activity 回调集合
     */
    private SparseArray<OnActivityCallback> mActivityCallbacks;
    public LoadIngDialogUtil loadIngDialogUtil;
    private boolean isShow;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        HttpHelper.getHttpHelper().getTokenStatus(this);
        loadIngDialogUtil = new LoadIngDialogUtil(this);
        initActivity();

    }

    /**
     * 需要接收事件 重写该方法 并返回true
     *
     * @return boolean
     */
    protected boolean registerEventBus() {
        return false;
    }

    /**
     * 子类接受事件 重写该方法
     *
     * @param event 事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBus(BusEvent event) {

    }

    /**
     * 子类接受事件 重写该方法
     *
     * @param event 事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onEventBusSticky(BusEvent event) {

    }

    protected void initActivity() {
        initLayout();
        setStatusBar();
        ButterKnife.bind(this);
        setBottomBarStatus();
        initEventBus();
        initView();
        initData();
    }

    public void initEventBus() {
        if (registerEventBus()) {
            LogsUtils.i("BaseActivity==", " EventBusUtils.register 方法");
            EventBusUtils.register(this);
        }
    }

    /**
     * 获取布局 ID
     */
    protected abstract int getLayoutId();

    /**
     * 初始化控件
     */
    protected abstract void initView();// 如果实现这个方法 必须super

    /**
     * 初始化数据
     */
    protected abstract void initData();

    /**
     * 初始化布局
     */
    protected void initLayout() {
        if (getLayoutId() > 0) {
            setContentView(getLayoutId());
            initSoftKeyboard();
        }
    }

    /**
     * 初始化软键盘
     */
    protected void initSoftKeyboard() {
        // 点击外部隐藏软键盘，提升用户体验
        getContentView().setOnClickListener(v -> {
            // 隐藏软键，避免内存泄漏
            hideKeyboard(getCurrentFocus());
        });
    }

    @Override
    public void onTokenPastDue() {
        LogsUtils.i("token", "token 过期  需要重新登录");

    }

    @Override
    protected void onResume() {
        super.onResume();
        isShow = true;
    }

    @Override
    protected void onPause() {
        super.onPause();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeCallbacks();
        if (registerEventBus()) {
            LogsUtils.i("BaseActivity 释放 EventBusUtils");
            EventBusUtils.unregister(this);
        }
    }

    public void removeLoadIngDialog() {
        isShow = false;
        if (loadIngDialogUtil != null) {
            loadIngDialogUtil.removeLoadDialog();
        }
    }

    @Override
    public void finish() {
        super.finish();
        // 隐藏软键，避免内存泄漏
        hideKeyboard(getCurrentFocus());
    }

    /**
     * 如果当前的 Activity（singleTop 启动模式） 被复用时会回调
     */
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // 设置为当前的 Intent，避免 Activity 被杀死后重启 Intent 还是最原先的那个
        setIntent(intent);
    }

    @Override
    public Bundle getBundle() {
        return getIntent().getExtras();
    }

    /**
     * 和 setContentView 对应的方法
     */
    public ViewGroup getContentView() {
        return findViewById(Window.ID_ANDROID_CONTENT);
    }

    @Override
    public Context getContext() {
        return this;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        List<Fragment> fragments = getSupportFragmentManager().getFragments();
        for (Fragment fragment : fragments) {
            // 这个 Fragment 必须是 BaseFragment 的子类，并且处于可见状态
            if (!(fragment instanceof BaseFragment) ||
                    fragment.getLifecycle().getCurrentState() != Lifecycle.State.RESUMED) {
                continue;
            }
            // 将按键事件派发给 Fragment 进行处理
            if (((BaseFragment<?>) fragment).dispatchKeyEvent(event)) {
                // 如果 Fragment 拦截了这个事件，那么就不交给 Activity 处理
                return true;
            }
        }
        return super.dispatchKeyEvent(event);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        // 隐藏软键，避免内存泄漏
        hideKeyboard(getCurrentFocus());
        // 查看源码得知 startActivity 最终也会调用 startActivityForResult
        super.startActivityForResult(intent, requestCode, options);
    }

    /**
     * startActivityForResult 方法优化
     */

    public void startActivityForResult(Class<? extends Activity> clazz, OnActivityCallback callback) {
        startActivityForResult(new Intent(this, clazz), null, callback);
    }

    public void startActivityForResult(Intent intent, OnActivityCallback callback) {
        startActivityForResult(intent, null, callback);
    }

    public void startActivityForResult(Intent intent, @Nullable Bundle options, OnActivityCallback callback) {
        if (mActivityCallbacks == null) {
            mActivityCallbacks = new SparseArray<>(1);
        }
        // 请求码必须在 2 的 16 次方以内
        int requestCode = new Random().nextInt((int) Math.pow(2, 16));
        mActivityCallbacks.put(requestCode, callback);
        startActivityForResult(intent, requestCode, options);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        OnActivityCallback callback;
        if (mActivityCallbacks != null && (callback = mActivityCallbacks.get(requestCode)) != null) {
            callback.onActivityResult(resultCode, data);
            mActivityCallbacks.remove(requestCode);
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    public interface OnActivityCallback {

        /**
         * 结果回调
         *
         * @param resultCode 结果码
         * @param data       数据
         */
        void onActivityResult(int resultCode, @Nullable Intent data);
    }


    /**
     * 正确提示
     *
     * @param msg
     */
    public void showRightToast(String msg) {
        EasyWindowUtils.getInstance().toShowXToastRight(this, msg, 3000);
    }

    /**
     * 提示
     *
     * @param msg
     */
    public void showTipToast(String msg, int duration) {
        EasyWindowUtils.getInstance().toShowXToastRight(this, msg, duration);
    }

    /**
     * 异常提示
     *
     * @param msg
     */
    public void showErrorToast(String msg) {
        EasyWindowUtils.getInstance().toShowXToastError(this, msg, 3000);
    }


//===============================状态栏的==============================================

    /**
     * 调用
     */
    public void setStatusBar() {
        setImmersionBarColor(R.color.transparent);
    }

    /**
     * 设置沉浸栏颜色
     *
     * @param statusBarColor 颜色
     */
    protected void setImmersionBarColor(int statusBarColor) {
        setImmersionBarColor(statusBarColor, false);
    }

    /**
     * 设置沉浸栏颜色
     *
     * @param statusBarColor 沉浸栏颜色
     */
    protected void setImmersionBarColor(int statusBarColor, boolean fitsSystemWindows) {
        setImmersionBarColor(statusBarColor, R.color.white, fitsSystemWindows);
    }

    /**
     * 设置沉浸栏颜色
     *
     * @param statusBarColor     沉浸栏颜色
     * @param navigationBarColor 沉浸栏图标颜色
     */
    protected void setImmersionBarColor(int statusBarColor, int navigationBarColor, boolean fitsSystemWindows) {
        ImmersionBar.with(this)
                .statusBarColor(statusBarColor)
                .navigationBarColor(navigationBarColor)
                .fitsSystemWindows(fitsSystemWindows)
                .autoDarkModeEnable(true)
                .statusBarDarkFont(true)
                .init();
    }

    /**
     * 隐藏状态栏、导航栏
     */
    protected void setImmersionBarHide() {
        ImmersionBar.with(this)
                .fitsSystemWindows(false)
                .hideBar(BarHide.FLAG_HIDE_BAR)
                .init();
    }

    /**
     * 显示状态栏、导航栏
     */
    protected void setImmersionBarShow() {
        ImmersionBar.with(this)
                .statusBarColor(R.color.transparent)
                .navigationBarColor(R.color.black)
                .fitsSystemWindows(false)
                .autoDarkModeEnable(true)
                .statusBarDarkFont(true)
                .init();
    }

    /**
     *
     * 设置底部导航栏 的界面兼容状态
     */
    protected void setBottomBarStatus(){

        //监听底部导航栏是否显示及添加间距
        View decorView = getWindow().getDecorView();
        decorView.setOnApplyWindowInsetsListener((v, insets) -> {
            boolean hasNavBar = insets.hasSystemWindowInsets();
            int navBarHeight = insets.getSystemWindowInsetBottom();
            if (hasNavBar) {
                adjustLayoutForNavigationBar(getContentView(), navBarHeight);
                ShareUtils.getInstance().putInt("NavigationBarHeight", navBarHeight);
            } else {
                ShareUtils.getInstance().putInt("NavigationBarHeight", 0);
            }
            LogsUtils.d("NavBar", "Has NavBar: " + hasNavBar + ", Height: " + navBarHeight);
            return insets;
        });
    }
    public void adjustLayoutForNavigationBar(View view, int navigationBarHeight) {
        // 获取当前布局参数
        ViewGroup.LayoutParams params = view.getLayoutParams();

        // 调整布局的底部margin
        if (view instanceof ViewGroup) {
            ((ViewGroup.MarginLayoutParams) params).bottomMargin = navigationBarHeight;
        }
        // 应用新的布局参数
        view.setLayoutParams(params);
    }

}